import md5 from "md5";
import { Model, DataTypes } from "sequelize";
import Sequelize from "./sequelize";
import { waitTime } from "./entity/util";

// 从环境变量中读取数据库配置
const {
  MYSQL_USERNAME = "root",
  MYSQL_PASSWORD = "Z123xc456&",
  MYSQL_ADDRESS = "localhost:3306",
} = process.env;

const [host, port = "80"] = MYSQL_ADDRESS.split(":");

export const sequelize = new Sequelize(
  "nodejs_demo",
  MYSQL_USERNAME,
  MYSQL_PASSWORD,
  {
    host,
    port: +port,
    dialect: "mysql" /* one of 'mysql' | 'mariadb' | 'postgres' | 'mssql' */,
    pool: {
      // 最多有多少个连接
      max: 10,
      // // 最少有多少个连接
      min: 0,
      // 当前连接多久没有操作就断开
      idle: 10000,
      // 多久没有获取到连接就断开
      acquire: 30000,
    },
  }
);

export async function authenticate() {
  async function _authenticate() {
    try {
      await sequelize.authenticate();
      return true;
    } catch (error) {
      return false;
    }
  }
  if (await _authenticate()) {
    console.log("数据库连接成功");
    return;
  }
  await waitTime(1000);
  await authenticate();
}

// 定义数据模型
export class Counter extends Model {}
Counter.init(
  {
    count: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 1,
    },
  },
  { sequelize }
);

export class User extends Model {}
User.init(
  {
    id: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    nickname: DataTypes.STRING,
    password: DataTypes.STRING,
    avatar: {
      type: DataTypes.TEXT,
      defaultValue:
        "https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png",
    },
    email: DataTypes.STRING,
    signature: DataTypes.STRING,
    title: DataTypes.STRING,
    group: DataTypes.STRING,
    phone: DataTypes.STRING,
    access: {
      type: DataTypes.STRING,
      defaultValue: "user",
    },
  },
  { sequelize }
);

export class EventLog extends Model {}
EventLog.init(
  {
    id: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
    },
    name: DataTypes.STRING,
    icon: DataTypes.STRING,
    color: DataTypes.STRING,
    startAt: {
      type: DataTypes.DATE,
      defaultValue: DataTypes.NOW,
    },
    endAt: DataTypes.DATE,
  },
  { sequelize }
);

export class EventLast extends Model {}
EventLast.init(
  {
    id: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
    },
  },
  { sequelize }
);

export class EventType extends Model {}
EventType.init(
  {
    id: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
    },
    name: DataTypes.STRING,
    icon: DataTypes.STRING,
    color: DataTypes.STRING,
    index: DataTypes.BIGINT,
  },
  {
    sequelize,
    // @ts-ignore
    hierarchy: true,
  }
);

// 建立一对多关联
User.hasMany(EventLog);
EventLog.belongsTo(User);

User.hasMany(EventType);
EventType.belongsTo(User);

User.hasOne(EventLast);
EventLast.belongsTo(User);
EventLog.hasOne(EventLast);
EventLast.belongsTo(EventLog);

// 数据库初始化方法
export async function init() {
  await authenticate();
  const admin = await User.findAll({ where: { name: "admin" } });
  // await sequelize.sync({ alter: true })
  // sequelize
  //   .query("SET FOREIGN_KEY_CHECKS = 0")
  //   .then(function () {
  //     return sequelize.query("truncate table EventTypes");
  //   })
  //   .then(function () {
  //     return sequelize.query("SET FOREIGN_KEY_CHECKS = 1");
  //   });

  if (!admin.length) {
    // 当前数据库不存在管理员，新增一个管理员
    User.create({ name: "admin", password: md5("123456"), access: "admin" });
  }
}
